package com.whu.service.impl;

import com.whu.UVAProtocol.UVAConnection;
import com.whu.UVAProtocol.UVAServer;
import com.whu.aircraft.PictureInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Slf4j
@Service
public class PictureService {
    @Value("${pic.path}")
    private String picPath;
    final PicInfoService picInfoService;

    @Autowired
    public PictureService(PicInfoService picInfoService) {
        this.picInfoService = picInfoService;
    }

    /**
     * 图片转BASE64
     * @param imagePath 路径
     * @return
     */


    public String imageChangeBase64(String imagePath){
        InputStream inputStream = null;
        byte[] data = null;
        try {
            inputStream = new FileInputStream(imagePath);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加密
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }

    /**
     * BASE转图片
     * @param baseStr  base64字符串
     * @param imagePath 生成的图片
     * @return
     */
    public boolean base64ChangeImage(String baseStr,String imagePath){
        if (baseStr == null){
            return false;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // 解密
            byte[] b = decoder.decodeBuffer(baseStr);
            // 处理数据
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            OutputStream out = new FileOutputStream(imagePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    public void base64ChangeImage(byte[] picBytes,String imagePath){
        String base64Str = new String(picBytes, StandardCharsets.US_ASCII);
        base64ChangeImage(base64Str,imagePath);
    }

    @Async("pictureServiceExecutor")
    public void base64ChangeImage(ArrayList<byte[]> picBytesList, String imagePath) {
        List<Byte> bl = new ArrayList<>();
        for(int i=0;i<picBytesList.size();i++){
            byte[] b = picBytesList.get(i);
            for(int j = 0;j<b.length;j++){
                bl.add(b[j]);
            }
        }
        int len = bl.size();
        byte[] picBytes = new byte[len];
        for(int i=0;i<len;i++){
            picBytes[i] = bl.get(i);
        }
        base64ChangeImage(picBytes,imagePath);
    }
    private void bytes2Pic(ArrayList<byte[]> picBytesList, String imagePath) throws IOException {
        //System.out.println(Thread.currentThread().getName()+"线程池执行任务");
        List<Byte> bl = new ArrayList<>();
        for(int i=0;i<picBytesList.size();i++){
            byte[] b = picBytesList.get(i);
            for(int j = 0;j<b.length;j++){
                bl.add(b[j]);
            }
        }
        int len = bl.size();
        byte[] picBytes = new byte[len];
        for(int i=0;i<len;i++){
            picBytes[i] = bl.get(i);
        }
        FileOutputStream out = new FileOutputStream(imagePath);
        out.write(picBytes);
        out.close();

    }
    @Async("pictureServiceExecutor")
    public void bytes2Pic(int index,HashMap<Integer,ArrayList<byte[]>> picCache, String imagePath) throws IOException {
        //System.out.println(Thread.currentThread().getName());
        ArrayList<byte[]> picBytesList  = picCache.get(index);
        bytes2Pic(picBytesList,imagePath);
        //移除缓冲中的对应图片
        picCache.remove(index);

    }

    /**
     * @Description
     * @Param [id, picBytes] id为无人机id,要把消息发送给对应无人机channel的队列中，需要id这个句柄
     * @Return void
     * @Author chengeng
     * @Date 2022/3/31 20:24
     **/
    @Transactional
    @Async("pictureServiceExecutor")
    public void bytes2Pic(int id,ArrayList<byte[]> picBytes) throws IOException {
        System.out.println(Thread.currentThread().getName());
        String imageName = UUID.randomUUID()+".jpg";
        String imagePath = this.picPath+imageName;
        bytes2Pic(picBytes,imagePath);

        PictureInfo pictureInfo = new PictureInfo();
        pictureInfo.setPicPath(new String(imagePath.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
        pictureInfo.setPicName(imageName);
        pictureInfo.setPicCreateTime(new Date());
        pictureInfo.setPicDescribe("{}");
        picInfoService.insertPicInfo(pictureInfo);

        UVAConnection connection = UVAServer.uvaConnections.get(id);
        boolean res = connection.getPicMsgQueue().offer(imagePath);
        if(!res){
            System.out.println("队列已满！");
        }
        picBytes.clear();
    }
    @Transactional
    @Async("pictureServiceExecutor")
    public void bytes2Pic(int id,ArrayList<byte[]> picBytes,int detect,double longitude,double latitude) throws IOException {
        System.out.println(Thread.currentThread().getName());
        String imageName = UUID.randomUUID()+".jpg";
        String imagePath = this.picPath+imageName;
        bytes2Pic(picBytes,imagePath);

        PictureInfo pictureInfo = new PictureInfo();
        pictureInfo.setPicPath(new String(imagePath.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
        pictureInfo.setPicName(imageName);
        pictureInfo.setPicCreateTime(new Date());
        pictureInfo.setPicDescribe("{}");
        pictureInfo.setDetect(detect);
        pictureInfo.setLongitude(longitude);
        pictureInfo.setLatitude(latitude);
        //TODO...:需要判断是否有违建违搭，无，则插入数据库；有，则不插入数据库，并且做相应的处理
        if(detect==0){
            String imageMatchRes = picInfoService.imageMatchRpc(pictureInfo);
            log.info("图片匹配："+imageMatchRes);
            if(imageMatchRes.equals("noIllegalBuilding")){
                //图片中没有发现违建违搭
                picInfoService.insertPicInfo(pictureInfo);//及时插入数据库

                UVAConnection connection = UVAServer.uvaConnections.get(id);
                boolean res = connection.getPicMsgQueue().offer(imagePath);//插入图片队列
                if(!res){
                    System.out.println("队列已满！");
                }
            }else {
                //图片中有疑似违搭
                log.info("发现违建！");
                ArrayList<String> pathList = new ArrayList<>();
                pathList.add(0,imagePath);
                pathList.add(1,imageMatchRes);
                UVAConnection connection = UVAServer.uvaConnections.get(id);
                connection.getPicIllegalBuildingsPairs().add(pathList);
            }
        }else{
            picInfoService.insertPicInfo(pictureInfo);//及时插入数据库
            UVAConnection connection = UVAServer.uvaConnections.get(id);
            boolean res = connection.getPicMsgQueue().offer(imagePath);//插入图片队列
            if(!res){
                System.out.println("队列已满！");
            }

        }

        picBytes.clear();

    }


}
